#ifndef __LL_COMMAND_BASE_HPP__
#define __LL_COMMAND_BASE_HPP__

#include "llToken.hpp"
#include "llLex.hpp"

#include <string>
#include <list>
#include <iostream>
using namespace std;

#include <boost/tr1/memory.hpp>
using namespace std::tr1;


namespace llmake
{
	class llMakeDirectory;
	typedef shared_ptr<llMakeDirectory> llMakeDirectoryPtr;

	// prototype of llCommandBase class
	class llCommandBase;
	typedef shared_ptr<llCommandBase> llCommandBasePtr;
	typedef list<llCommandBasePtr> llCommandList;

/// Command Base
	class llCommandBase
	{
// method
	public:
		llCommandBase(const string &name,const llTokenList &tokenList,llMakeDirectoryPtr owner)
		 :m_Name(name)
		 ,m_Tokens(tokenList)
		 ,m_Owner(owner)
		{
#ifdef DEBUG			
			cout<<"create command with tokens={"<<endl;
			for(llTokenList::iterator iter = m_Tokens.begin();iter != m_Tokens.end(); ++iter)
			{
				cout<<"<"<<iter->m_Token<<">,";
			}
			cout<<endl<<"}"<<endl;
#endif
			// remove command 
			m_Tokens.pop_front();
			// remove "("
			m_Tokens.pop_front();
			// remove ")"
			m_Tokens.pop_back();

#ifdef DEBUG			
			cout<<"create command with tokens={"<<endl;
			for(llTokenList::iterator iter = m_Tokens.begin();iter != m_Tokens.end(); ++iter)
			{
				cout<<"<"<<iter->m_Token<<">,";
			}
			cout<<endl<<"}"<<endl;
#endif			
		}
		~llCommandBase(){}
		virtual void parseCommand(llCommandList &commands)
		{}
		void dumpCommands(llCommandList &commands);
// members
	public:
		string 						m_Name;
		llTokenList 				m_Tokens;
		llMakeDirectoryPtr			m_Owner;
	protected:
		string parseSource(void);
		
	};

/// llPreProcessCommand Base
	class llPreProcessCommand:public llCommandBase
	{
// method
	public:
		llPreProcessCommand(const string &name,const llTokenList &tokenList,llMakeDirectoryPtr owner)
		 :llCommandBase(name,tokenList,owner)
		{
		}
		~llPreProcessCommand(){}
		virtual void preProcess(llCommandList &commandsSrc)
		{
//#ifdef DEBUG			
			cout<<"preProcess command ["<<m_Name<<"]"<<endl;
//#endif
			commandsSrc.pop_front();
		}
		virtual void parseCommand(llCommandList &commands)
		{
			this->preProcess(commands);
		}
// members
	private:
	};

/// llCompileCommand Base
	class llCompileCommand:public llCommandBase
	{
// method
	public:
		llCompileCommand(const string &name,const llTokenList &tokenList,llMakeDirectoryPtr owner)
		 :llCommandBase(name,tokenList,owner)
		{
		}
		~llCompileCommand(){}
		virtual void parseCommand(llCommandList &commands)
		{
			this->parseCompileCommand();
			commands.pop_front();
		}
		virtual void parseCompileCommand(void)
		{
#ifdef DEBUG			
			cout<<"parseCompileCommand command ["<<m_Name<<"]"<<endl;
#endif
		}
// members
	private:
	};
	
};

#endif // __LL_COMMAND_BASE_HPP__
